package com.pshare.excel.manager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;

import com.pshare.constant.SeaxConstants;
import com.pshare.excel.bean.ExcelExport;
import com.pshare.util.DateUtils;
import com.pshare.util.FileUtils;
import com.pshare.util.SysPropertyUtils;

/**
 * 将数据导入至excel
 */
@Service
public class ExcelManager {

	private static final Logger logger = Logger.getLogger(ExcelManager.class);

	private static final String basePath = FileUtils.toLocalFilePath(SysPropertyUtils.getProperty("excel.basedir"));

	/**
	 * @param sheetName sheet标题名
	 * @param headers 列名
	 * @param columnWidth 列宽
	 * @param dataset 需要显示的数据集合
	 * @return HSSFWorkbook 工作薄
	 */
	@SuppressWarnings("unchecked")
	private <T> SXSSFWorkbook createWorkbook(String sheetName, String[] headers, String getterMethods[],
			short[] columnWidth, Collection<T> dataset) {

		// 声明一个工作薄
		SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
		// 生成一个sheet
		Sheet sheet = workbook.createSheet(sheetName);

		// 设置headers
		Row row = sheet.createRow(0);
		for (short i = 0; i < headers.length; i++) {
			Cell cell = row.createCell(i);
			HSSFRichTextString text = new HSSFRichTextString(headers[i]);
			cell.setCellValue(text);
			// 并设置header对应的列的宽度
			if (columnWidth.length == 0) {
				sheet.setDefaultColumnWidth(50);
			} else {
				sheet.setColumnWidth(i, columnWidth[i]);
			}
		}

		// 遍历集合数据，产生数据行
		Iterator<T> it = dataset.iterator();
		int index = 0;
		while (it.hasNext()) {
			index++;
			row = sheet.createRow(index);
			T t = (T) it.next();
			for (short i = 0; i < getterMethods.length; i++) {

				Cell cell = row.createCell(i);// 开辟一个小格子
				String getMethodName = getterMethods[i].trim();
				try {
					Class tCls = t.getClass();
					Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
					Object value = getMethod.invoke(t, new Object[] {});

					String textValue = null;
					// 处理时间
					if (value instanceof Date) {
						Date date = (Date) value;
						SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.LONG_DATE_FORMAT);
						textValue = sdf.format(date);
					} else {
						// 其它数据类型都当作字符串简单处理
						if (value != null) {
							textValue = value.toString();
						} else {
							textValue = SeaxConstants.BLANK;
						}
					}

					// 设置field
					if (textValue != null) {
						HSSFRichTextString richString = new HSSFRichTextString(textValue);
						// Font font3 = workbook.createFont();
						// font3.setColor(HSSFColor.BLUE.index);
						// richString.applyFont(font3);
						cell.setCellValue(richString);
					}
				} catch (Exception ex) {
					StackTraceElement[] ste = ex.getStackTrace();
					logger.error("发生异常的类：" + ste[0].getFileName() + " 代码行:" + ste[0].getLineNumber() + " 异常信息："
							+ ex.toString());
				}
			}
		}
		return workbook;
	}

	/**
	 * 在服务器上生成excel文件
	 * 
	 * @param excelExport
	 * @param fileName
	 * @return filePath
	 */
	public <T> String createExcelFileOnServer(ExcelExport<T> excelExport, String fileName) {
		if (StringUtils.isBlank(fileName)) {
			logger.info("fileName is bank");
		}

		File folder = new File(basePath);
		if (!folder.exists()) {
			folder.mkdir();
		}

		String fileFullPath = basePath + fileName;

		SXSSFWorkbook excel = createWorkbook(excelExport.getSheetName(), excelExport.getHeaders(),
				excelExport.getGetterMethodName(), excelExport.getColumnWidth(), excelExport.getDataset());
		try {
			OutputStream out = new FileOutputStream(fileFullPath);
			excel.write(out);
			out.flush();
			out.close();
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
		return fileFullPath;
	}

	@SuppressWarnings("static-access")
	private String getValue(HSSFCell hssfCell) {
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			// 返回布尔类型的值
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			// 返回数值类型的值
			return String.valueOf(hssfCell.getNumericCellValue());
		} else {
			// 返回字符串类型的值
			return String.valueOf(hssfCell.getStringCellValue());
		}
	}

}
